package rudia.org.core;

import java.lang.reflect.Method;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

public class Rutil  extends ReloadableResourceBundleMessageSource  implements ApplicationContextAware,MessageSource {

	public static Logger log = Logger.getLogger("");
	private static ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource;

	public static ApplicationContext applicationContext;

	@SuppressWarnings("rawtypes")
	private static ArrayList programList;

	@SuppressWarnings("static-access")
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
		log.info("EgovComIndexController setApplicationContext method has called!");
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static List getProgramList(String pdiv) {

		if (programList == null) {
			programList = new ArrayList();

			RequestMapping requestMappingAnnotation;
			ProgramInfo programInfoAnnotation;
			// ProgramInfoVO programInfoVO;
			RuMap programInfoVO;

			/*
			 * @Controller Annotation 처리된 클래스를 모두 찾는다. Controller Class 내에서 호출
			 * 해야 작동한다.
			 */
			Map<String, Object> controllerZooMap = Rutil.applicationContext.getBeansWithAnnotation(Controller.class);
			for (final Object controllerZoo : controllerZooMap.values()) {
				Class<? extends Object> controllerClzz = controllerZoo.getClass();

				Method[] methods = controllerClzz.getMethods();
				for (int i = 0; i < methods.length; i++) {

					/*
					 * 1. ProgramInfo.class 우선으로 담기// 메뉴 설정시 중요 리소스만 보기 위해(임시 차후
					 * 모든 메서드에 주석을 달아 pdiv 로 구분)
					 */
					// programInfoAnnotation =
					// methods[i].getAnnotation(ProgramInfo.class);
					// if (programInfoAnnotation != null &&
					// CRUDDivCd.MENU_ABLE.getCode().equals(pdiv)) {
					// programInfoVO = new RuMap();
					// // programInfoVO.put("program_cd",
					// programInfoAnnotation.pid());
					// programInfoVO.put("program_cd", methods[i].getName() +
					// "." + controllerClzz.getSimpleName() + "." +
					// controllerClzz.getPackage());
					// programInfoVO.put("program_nm",
					// programInfoAnnotation.pnm());
					// programInfoVO.put("program_nme",
					// programInfoAnnotation.pnme());
					// programInfoVO.put("program_div",
					// programInfoAnnotation.pdiv());
					// programInfoVO.put("program_dc",
					// programInfoAnnotation.desc());
					// programInfoVO.put("program_ordr",
					// programInfoAnnotation.order());
					//
					// /* url 매핑은 @RequestMapping에서 가져온다 */
					// requestMappingAnnotation =
					// methods[i].getAnnotation(RequestMapping.class);
					// if (programInfoAnnotation != null) {
					// programInfoVO.put("program_url",
					// requestMappingAnnotation.value()[0]);
					// }
					// programList.add(programInfoVO);// Jqgrid 를 위한
					// }// end if

					/*
					 * 1. RequestMapping.class 우선으로 담기//권한정리 하기 위해 전체 리소스를 보기
					 * 위해(임시 차후 모든 메서드에 주석을 달아 pdiv 로 구분)
					 */
					requestMappingAnnotation = methods[i].getAnnotation(RequestMapping.class);
					if (requestMappingAnnotation != null) {
						programInfoVO = new RuMap();
						String pckg = controllerClzz.getPackage().toString();
						pckg = pckg.substring(pckg.indexOf(" "), pckg.length());
						programInfoVO.put("program_cd", pckg + "." + controllerClzz.getSimpleName() + "." + methods[i].getName());
						programInfoVO.put("program_url", requestMappingAnnotation.value()[0]);
						programInfoAnnotation = methods[i].getAnnotation(ProgramInfo.class);
						if (programInfoAnnotation != null && CRUDDivCd.MENU_ABLE.getCode().equals(pdiv)) {
							programInfoVO.put("program_nm", programInfoAnnotation.pnm());
							programInfoVO.put("program_nme", programInfoAnnotation.pnme());
							programInfoVO.put("program_div", programInfoAnnotation.pdiv());
							programInfoVO.put("program_dc", programInfoAnnotation.desc());
							programInfoVO.put("program_ordr", programInfoAnnotation.order());
						}// end if
						programList.add(programInfoVO);// Jqgrid 를 위한
					}

				}// end method for

				Collections.sort(programList, new Comparator<RuMap>() {
					public int compare(RuMap obj1, RuMap obj2) {
						return Collator.getInstance().compare(obj1.get("program_url"), obj2.get("program_url")); // compare(String,String)
					}
				});

			}// end class for
		}// END if (return == null)

		return programList;
	}

	
	/*Message start*/
	public void setReloadableResourceBundleMessageSource(ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource) {
		this.reloadableResourceBundleMessageSource = reloadableResourceBundleMessageSource;
	}
	public static ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
		return reloadableResourceBundleMessageSource;
	}
	public static String getMsg(String code) {
		return getReloadableResourceBundleMessageSource().getMessage(code, null, Locale.getDefault());
	}

	/*Message End*/

	
	public static String getCurrentTime(String formatter) {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat(formatter);
		return dateFormat.format(calendar.getTime());
	}

	public static String changeComma(String date, String ori, String chg) {
		date = date.replaceAll(ori, chg);

		return date;

	}

	/* 한글 초성 검색 시작부분 */
	static final char[] first = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };
	final char[] middle = { 'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ' }; // last // 0~20
	final char[] last = { ' ', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' }; // last// 0~27
	public static final String lastHangule = "힣";

	private static int isInitialSound(char c) {
		for (int i = 0; i < first.length; i++) {
			if (first[i] == c) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 한글 한 글자(char)를 받아 초성, 중성, 종성의 위치를 int[]로 반환 한다.
	 * 
	 * @param char : 한글 한 글자
	 * @return int[] : 한글 초, 중, 종성의 위치( ex:가 0,0,0 )
	 */
	public static int[] unicodeSplit(char c) {
		int arrChar[] = new int[4];

		// log.debug("***test : "+Integer.toHexString("가".charAt(0)));//hex변환방법
		if (c >= 0xAC00 && c <= 0xD7A3) {// 초중종한글
			arrChar[0] = (c - 0xAC00) / (21 * 28); // 초성의 위치
			arrChar[1] = ((c - 0xAC00) % (21 * 28)) / 28; // 중성의 위치
			arrChar[2] = (c - 0xAC00) % (28);// 종성의 위치
			arrChar[3] = 2;
		} else if (c >= 0x3130 && c <= 0x318E) {// 자음이면
			arrChar[0] = isInitialSound(c);
			arrChar[1] = 0;
			arrChar[2] = 0;
			arrChar[3] = 1;
		} else {
			arrChar[0] = c;
			arrChar[1] = 0;
			arrChar[2] = 0;
			arrChar[3] = 3;
		}
		return arrChar;
	}

	/**
	 * 한글 한 글자를 구성 할 초성, 중성, 종성을 받아 조합 후 char[]로 반환 한다.
	 * 
	 * @param int[] : 한글 초, 중, 종성의 위치( ex:가 0,0,0 )
	 * @return char[] : 한글 한 글자
	 */
	public static char combine(int[] sub) {
		char ch = (char) (0xAC00 + (sub[0] * 21 * 28) + (sub[1] * 28) + sub[2]);
		return ch;
	}

	public static String getClntOsInfo(HttpServletRequest request) throws Exception {

		String os = null;
		String user_agent = request.getHeader("user-agent");

		if (user_agent.toLowerCase().indexOf("windows") >= 0) {
			os = "Windows";
		} else if (user_agent.toLowerCase().indexOf("mac") >= 0) {
			os = "Mac";
		} else if (user_agent.toLowerCase().indexOf("x11") >= 0) {
			os = "Unix";
		} else if (user_agent.toLowerCase().indexOf("apache") >= 0) {
			os = "Apache";
		} else if (user_agent.toLowerCase().indexOf("android") >= 0) {
			os = "Android";
		} else if (user_agent.toLowerCase().indexOf("iphone") >= 0) {
			os = "IPhone";
		} else {
			os = "UnKnown, More-Info: " + user_agent;
		}

		return os;
	}

	public static String getClntWebKind(HttpServletRequest request) throws Exception {

		String browser = "";
		String userAgent = request.getHeader("User-Agent");
		if (userAgent.indexOf("Trident") > 0 || userAgent.indexOf("MSIE") > 0) {
			browser = "IE";
		} else if (userAgent.indexOf("Opera") > 0) {
			browser = "Opera";
		} else if (userAgent.indexOf("Firefox") > 0) {
			browser = "Firefox";
		} else if (userAgent.indexOf("Safari") > 0) {
			if (userAgent.indexOf("Chrome") > 0) {
				browser = "Chrome";
			} else {
				browser = "Safari";
			}
		} else {
			browser = "ETC";

		}
		return browser;
	}

}
